package com.kingmed.kmss.framework.feign.client.bpmn;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.kingmed.kmss.common.bo.bpmn.*;
import com.kingmed.kmss.common.constant.bpmn.BpmnConstant;
import com.kingmed.kmss.common.dto.admin.ums.AdminDTO;
import com.kingmed.kmss.common.dto.bpmn.BizApprovalTrailDTO;
import com.kingmed.kmss.common.enums.bpmn.ProcessType;
import com.kingmed.kmss.common.exception.InternalApiException;
import com.kingmed.kmss.common.qc.bpmn.ApprovalTrailQC;
import com.kingmed.kmss.common.qc.bpmn.MyTaskQC;
import com.kingmed.kmss.common.vo.CommonPage;
import com.kingmed.kmss.common.vo.CommonResponse;
import com.kingmed.kmss.framework.feign.client.admin.CommonAdminFeignService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 供业务模块调用
 */
@Slf4j
@Component
public class CommonBpmnFeignServiceFacade {

	@Autowired
	private CommonBpmnFeignService bpmnFeignService;

	@Autowired
	private CommonAdminFeignService adminFeignService;

	/**
	 * 流程启动
	 * @param bizType 业务类型
	 * @param bizId 业务表主键ID
	 * @param processKey 流程定义key，xml中的process ID
	 * @param comment 提交/审批意见
	 * @param userId 流程发起人(一般对应admin模块的username)
	 * @param parentOrgId 流程发起人所在上级组织orgId（子公司或大区级）
	 * @param orgType 组织类型-1=子公司， 2=大区， 3=集团
	 * @param processType 流程审批类型
	 * @param varMap 其他需要放到流程中数据
	 * @return
	 */
	public BpmnBO startProcess(String bizType, String bizId, String processKey, String comment, String userId, Long parentOrgId, int orgType,
							   ProcessType processType, Map<String, Object> varMap) {
		ProcessStarterBO starter = new ProcessStarterBO();
		starter.setBusinessId(bizId);
		starter.setBusinessType(bizType);
		starter.setProcDefKey(processKey);
		starter.setComment(comment);
		starter.setStartUserId(userId);
		starter.setParentOrgId(parentOrgId);
		starter.setOrgType(orgType);
		
		ProcessVariableBO varBo = new ProcessVariableBO();
		varBo.setVarMap(varMap);
		starter.setProcessType(processType);
		starter.setProcVars(varBo);
		
		CommonResponse<BpmnBO> response = bpmnFeignService.startProcessInstance(starter);
		log.debug("启动流程: {}-{}", bizType, bizId);
		
		if (response.getCode() == HttpStatus.HTTP_UNAUTHORIZED || BeanUtil.isEmpty(response.getData())) {
			String msg = "启动流程没有返回数据: " + response.getMessage();
			log.debug(msg);
			if (StringUtils.isNotEmpty(response.getMessage())) {
				msg = response.getMessage();
			} else {
				msg = "无法重复提交审批";
			}
			throw new InternalApiException(msg);
		}
		
		if (response.getCode() == HttpStatus.HTTP_INTERNAL_ERROR) {
			throw new InternalApiException("启动流程失败： " + response.getData());
		}
		return response.getData();
	}
	
	public String completeTask(TaskExBO task) {
		
		log.debug("完成流程Task: " + task);
		CommonResponse<List<TaskBO>> response = bpmnFeignService.complete(task);
		
		
		if (response.getCode() == HttpStatus.HTTP_UNAUTHORIZED 
				//|| BeanUtil.isEmpty(response.getData())
				) {
			String msg = "工作流引擎错误: " + response.getMessage();
			log.error(msg + response);
			throw new InternalApiException(msg);
		}
		TaskBO nextTask = null;
		List<TaskBO> nextTasks = response.getData();
		if (CollUtil.isEmpty(nextTasks)) {
			String msg = "没有下一个任务，流程可能已结束";
			log.debug(msg);
		} else {
			nextTask = nextTasks.get(0);
			log.debug("下一个任务: " + nextTask);			
		}
		
		return nextTask!=null? nextTask.getTaskId():"";
	}
	
	public List<BizApprovalTrailDTO> getApprovalTrail(String businessType, String businessId) {
		ApprovalTrailQC param = new ApprovalTrailQC();
		param.setBusinessType(businessType);
		param.setBusinessId(businessId);

		CommonResponse<List<BizApprovalTrailDTO>> response = bpmnFeignService.approvalTrail(param);
		log.debug("读取审批跟踪记录: " + param);
		
		if (response.getCode() == HttpStatus.HTTP_UNAUTHORIZED || BeanUtil.isEmpty(response.getData())) {
			log.debug("读取审批跟踪记录没有返回数据: " + response.getData());
			return null;
		}
		
		
		return response.getData();
	}

	public TaskBO findTask(String taskId){
		CommonResponse<TaskBO> response = bpmnFeignService.findTask(taskId);
		log.info("调用admin工程字典查询接口成功，出参：{}", response);
		if (HttpStatus.HTTP_OK == response.getCode()) {
			return response.getData();
		}
		return null;
	}

	public BpmnBO startUpAndSubmit(String bizType, String bizId, String processKey, String comment, String bizTitle, String userId, Long parentOrgId, int orgType,
								   Map<String, Object> varMaps, Consumer<BpmnBO> consumer){
		
		varMaps.put(BpmnConstant.VarKeys.BIZ_TITLE, bizTitle);
		BpmnBO bpmnBO = startProcess(bizType, bizId, processKey, comment, userId, parentOrgId, orgType, ProcessType.NORMAL, varMaps);
		String taskId = bpmnBO.getFocusTaskBO().getTaskId();
		
		if(StrUtil.isNotEmpty(taskId)){
			TaskExBO task = new TaskExBO();
			task.setBizType(bizType);
			task.setApproved(null);
			task.setComment(comment);
			task.setStartUserId(userId);
			task.setTaskId(taskId);
			task.setBizId(bizId);
			task.setBizTitle(bizTitle);
	//		taskId = completeTask(task);
			bpmnBO.getFocusTaskBO().setTaskId(taskId);
		}
		consumer.accept(bpmnBO);
		return bpmnBO;
	}


	public List<TaskBO> findTodoTask(MyTaskQC param){
		CommonResponse<CommonPage<TaskBO>> response = bpmnFeignService.findTodoTask(param);
		log.info("调用查询用户待办接口成功，出参：{}", response);
		if (HttpStatus.HTTP_OK == response.getCode() && response.getData()!=null) {
			return response.getData().getList();
		}
		return null;
	}

	public boolean hasTodoTask(Long userId){
		List<TaskBO> taskList = null;
		MyTaskQC taskQC = new MyTaskQC();
		CommonResponse<AdminDTO> response = adminFeignService.loadById(userId);
		if (HttpStatus.HTTP_OK == response.getCode() && response.getData()!=null) {
			taskQC.setUserId(response.getData().getUsername());
			taskList = findTodoTask(taskQC);
		}
		return CollectionUtil.isNotEmpty(taskList);
	}


}
